home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 February / PCWorld_2006-02_cd.bin / software / vyzkuste / triky / triky.exe / httrack-3.33.exe / {app} / src / htsbauth.c < prev    next >
C/C++ Source or Header  |  2004-05-09  |  13KB  |  415 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       basic authentication: password storage                 */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. /* Internal engine bytecode */
  39. #define HTS_INTERNAL_BYTECODE
  40.  
  41. #include "htsbauth.h"
  42.  
  43. /* specific definitions */
  44. #include "htsglobal.h"
  45. #include "htslib.h"
  46.  
  47. #include "htsnostatic.h"
  48.  
  49. /* END specific definitions */
  50.  
  51. // gestion des cookie
  52. // ajoute, dans l'ordre
  53. // !=0 : erreur
  54. int cookie_add(t_cookie* cookie,char* cook_name,char* cook_value,char* domain,char* path) {
  55.   char* a=cookie->data;
  56.   char* insert;
  57.   char cook[16384];
  58.   // effacer Θventuel cookie en double
  59.   cookie_del(cookie,cook_name,domain,path);
  60.   if ((int)strlen(cook_value)>1024) return -1;                              // trop long
  61.   if ((int)strlen(cook_name)>256) return -1;                                // trop long
  62.   if ((int)strlen(domain)>256) return -1;                                   // trop long
  63.   if ((int)strlen(path)>256) return -1;                                     // trop long
  64.   if ((int)(
  65.     strlen(cookie->data)
  66.     +strlen(cook_value)
  67.     +strlen(cook_name)
  68.     +strlen(domain)
  69.     +strlen(path)
  70.     +256
  71.     ) > cookie->max_len) return -1;               // impossible d'ajouter
  72.  
  73.   insert=a;          // insΘrer ici
  74.   while (*a) {
  75.     if ( strlen(cookie_get(a,2)) <  strlen(path) )      // long. path (le + long est prioritaire)
  76.       a=cookie->data+strlen(cookie->data);    // fin
  77.     else {
  78.       a=strchr(a,'\n');     // prochain champ
  79.       if (a==NULL)
  80.         a=cookie->data+strlen(cookie->data);    // fin
  81.       else
  82.         a++;
  83.       while(*a=='\n') a++;
  84.       insert=a;          // insΘrer ici
  85.     }
  86.   }
  87.   // construction du cookie
  88.   strcpybuff(cook,domain);
  89.   strcatbuff(cook,"\t");
  90.   strcatbuff(cook,"TRUE");
  91.   strcatbuff(cook,"\t");
  92.   strcatbuff(cook,path);
  93.   strcatbuff(cook,"\t");
  94.   strcatbuff(cook,"FALSE");
  95.   strcatbuff(cook,"\t");
  96.   strcatbuff(cook,"1999999999");
  97.   strcatbuff(cook,"\t");
  98.   strcatbuff(cook,cook_name);
  99.   strcatbuff(cook,"\t");
  100.   strcatbuff(cook,cook_value);
  101.   strcatbuff(cook,"\n");
  102.   if (!( ((int) strlen(cookie->data) + (int) strlen(cook)) < cookie->max_len)) return -1;      // impossible d'ajouter
  103.   cookie_insert(insert,cook);
  104. #if DEBUG_COOK
  105.   printf("add_new cookie: name=\"%s\" value=\"%s\" domain=\"%s\" path=\"%s\"\n",cook_name,cook_value,domain,path);
  106.   //printf(">>>cook: %s<<<\n",cookie->data);
  107. #endif
  108.   return 0;
  109. }
  110.  
  111. // effacer cookie si existe
  112. int cookie_del(t_cookie* cookie,char* cook_name,char* domain,char* path) {
  113.   char *a,*b;
  114.   b=cookie_find(cookie->data,cook_name,domain,path);
  115.   if (b) {
  116.     a=cookie_nextfield(b);
  117.     cookie_delete(b,(int) (a - b));
  118. #if DEBUG_COOK
  119.     printf("deleted old cookie: %s %s %s\n",cook_name,domain,path);
  120. #endif
  121.   }
  122.   return 0;
  123. }
  124.  
  125. // rechercher cookie α partir de la position s (par exemple s=cookie.data)
  126. // renvoie pointeur sur ligne, ou NULL si introuvable
  127. // path est alignΘ α droite et cook_name peut Ωtre vide (chercher alors tout cookie)
  128. // .doubleclick.net    TRUE    /    FALSE    1999999999    id    A
  129. char* cookie_find(char* s,char* cook_name,char* domain,char* path) {
  130.   char* a=s;
  131.   while (*a) {
  132.     int t;
  133.     if (strnotempty(cook_name)==0)
  134.       t=1;                      // accepter par dΘfaut
  135.     else
  136.       t=( strcmp(cookie_get(a,5),cook_name)==0 );     // tester si mΩme nom
  137.     if (t) {  // mΩme nom ou nom qualconque
  138.       //
  139.       char* chk_dom=cookie_get(a,0);       // domaine concernΘ par le cookie
  140.       if ((int) strlen(chk_dom) <= (int) strlen(domain)) {
  141.         if ( strcmp(chk_dom,domain+strlen(domain)-strlen(chk_dom))==0 ) {  // mΩme domaine
  142.           //
  143.           char* chk_path=cookie_get(a,2);       // chemin concernΘ par le cookie
  144.           if ((int) strlen(chk_path) <= (int) strlen(path)) {
  145.             if (strncmp(path,chk_path,strlen(chk_path))==0 ) { // mΩme chemin
  146.               return a;
  147.             }
  148.           }
  149.         }
  150.       }
  151.     }
  152.     a=cookie_nextfield(a);
  153.   }
  154.   return NULL;
  155. }
  156.  
  157. // renvoie prochain champ
  158. char* cookie_nextfield(char* a) {
  159.   char* b=a;
  160.   a=strchr(a,'\n');     // prochain champ
  161.   if (a==NULL)
  162.     a=b+strlen(b);    // fin
  163.   else
  164.     a++;
  165.   while(*a=='\n') a++;
  166.   return a;
  167. }
  168.  
  169. // lire cookies.txt
  170. // lire Θgalement (Windows seulement) les *@*.txt (cookies IE copiΘs)
  171. // !=0 : erreur
  172. int cookie_load(t_cookie* cookie,char* fpath,char* name) {
  173.  //  cookie->data[0]='\0';
  174.  
  175.   // Fusionner d'abord les Θventuels cookies IE
  176. #if HTS_WIN
  177.   {
  178.     WIN32_FIND_DATAA find;
  179.     HANDLE h;
  180.     char  pth[MAX_PATH + 32];
  181.     strcpybuff(pth,fpath);
  182.     strcatbuff(pth,"*@*.txt");
  183.     h = FindFirstFileA((char*)pth,&find);
  184.     if (h != INVALID_HANDLE_VALUE) {
  185.       do {
  186.         if (!(find.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY ))
  187.           if (!(find.dwFileAttributes  & FILE_ATTRIBUTE_SYSTEM )) {
  188.             FILE* fp=fopen(fconcat(fpath,find.cFileName),"rb");
  189.             if (fp) {
  190.               char cook_name[256];
  191.               char cook_value[1000];
  192.               char domainpathpath[512];
  193.               char dummy[512];
  194.               //
  195.               char domain[256];           // domaine cookie (.netscape.com)
  196.               char path[256];             // chemin (/)
  197.               int cookie_merged=0;
  198.               //
  199.               // Read all cookies
  200.               while( ! feof(fp) ) {
  201.                 cook_name[0] = cook_value[0] = domainpathpath[0] 
  202.                   = dummy[0] = domain[0] = path[0] = '\0';
  203.                 linput(fp,cook_name,250);
  204.                 if ( ! feof(fp) ) {
  205.                   linput(fp,cook_value,250);
  206.                   if ( ! feof(fp) )  {
  207.                     int i;
  208.                     linput(fp,domainpathpath,500);
  209.                     /* Read 6 other useless values */
  210.                     for(i = 0 ; ! feof(fp) && i < 6 ; i++) {
  211.                       linput(fp,dummy,500);
  212.                     }
  213.                     if (strnotempty(cook_name) 
  214.                       && strnotempty(cook_value) 
  215.                       && strnotempty(domainpathpath)) {
  216.                       if (ident_url_absolute(domainpathpath,domain,path)>=0) {
  217.                         cookie_add(cookie,cook_name,cook_value,domain,path);
  218.                         cookie_merged=1;
  219.                       }
  220.                     }
  221.                   }
  222.                 }
  223.               }
  224.               fclose(fp);
  225.               if (cookie_merged)
  226.                 remove(fconcat(fpath,find.cFileName));
  227.             }  // if fp
  228.           }
  229.       } while(FindNextFileA(h,&find));
  230.       FindClose(h);
  231.     }
  232.   }
  233. #endif
  234.   
  235.   // Ensuite, cookies.txt
  236.   {
  237.     FILE* fp = fopen(fconcat(fpath,name),"rb");
  238.     if (fp) {
  239.       char BIGSTK line[8192];
  240.       while( (!feof(fp)) && (((int) strlen(cookie->data)) < cookie->max_len)) {
  241.         rawlinput(fp,line,8100);
  242.         if (strnotempty(line)) {
  243.           if (strlen(line)<8000) {
  244.             if (line[0]!='#') {
  245.               char domain[256];           // domaine cookie (.netscape.com)
  246.               char path[256];             // chemin (/)
  247.               char cook_name[256];        // nom cookie (MYCOOK)
  248.               char BIGSTK cook_value[8192];      // valeur (ID=toto,S=1234)
  249.               strcpybuff(domain,cookie_get(line,0));       // host
  250.               strcpybuff(path,cookie_get(line,2));         // path
  251.               strcpybuff(cook_name,cookie_get(line,5));    // name
  252.               strcpybuff(cook_value,cookie_get(line,6));   // value
  253. #if DEBUG_COOK
  254.               printf("%s\n",line);
  255. #endif
  256.               cookie_add(cookie,cook_name,cook_value,domain,path);
  257.             }
  258.           }
  259.         }
  260.       }
  261.       fclose(fp);
  262.       return 0;
  263.     }
  264.   }
  265.   return -1;
  266. }
  267.  
  268. // Θcrire cookies.txt
  269. // !=0 : erreur
  270. int cookie_save(t_cookie* cookie,char* name) {
  271.   if (strnotempty(cookie->data)) {
  272.     char BIGSTK line[8192];
  273.     FILE* fp = fopen(fconv(name),"wb");
  274.     if (fp) {
  275.       char* a=cookie->data;
  276.       fprintf(fp,"# HTTrack Website Copier Cookie File"LF"# This file format is compatible with Netscape cookies"LF);
  277.       do {
  278.         a+=binput(a,line,8000);
  279.         fprintf(fp,"%s"LF,line);
  280.       } while(strnotempty(line));
  281.       fclose(fp);
  282.       return 0;
  283.     }
  284.   } else
  285.     return 0;
  286.   return -1;
  287. }
  288.  
  289. // insertion chaine ins avant s
  290. void cookie_insert(char* s,char* ins) {
  291.   char* buff;
  292.   if (strnotempty(s)==0) {    // rien α faire, juste concat
  293.     strcatbuff(s,ins);
  294.   } else {
  295.     buff=(char*) malloct(strlen(s)+2);
  296.     if (buff) {
  297.       strcpybuff(buff,s);     // copie temporaire
  298.       strcpybuff(s,ins);      // insΘrer
  299.       strcatbuff(s,buff);     // copier
  300.       freet(buff);
  301.     }
  302.   }
  303. }
  304. // destruction chaine dans s position pos
  305. void cookie_delete(char* s,int pos) {
  306.   char* buff;
  307.   if (strnotempty(s+pos)==0) {    // rien α faire, effacer
  308.     s[0]='\0';
  309.   } else {
  310.     buff=(char*) malloct(strlen(s+pos)+2);
  311.     if (buff) {
  312.       strcpybuff(buff,s+pos);     // copie temporaire
  313.       strcpybuff(s,buff);         // copier
  314.       freet(buff);
  315.     }
  316.   }
  317. }
  318.  
  319. // renvoie champ param de la chaine cookie_base
  320. // ex: cookie_get("ceci est<tab>un<tab>exemple",1) renvoi "un"
  321. char* cookie_get(char* cookie_base,int param) {
  322.   char* buffer;
  323.   //
  324.   char * limit;
  325.   NOSTATIC_RESERVE(buffer, char, 8192);
  326.  
  327.   while(*cookie_base=='\n') cookie_base++;
  328.   limit = strchr(cookie_base,'\n');
  329.   if (!limit) limit=cookie_base+strlen(cookie_base);
  330.   if (limit) {
  331.     if (param) {
  332.       int i;
  333.       for(i=0;i<param;i++) {
  334.         if (cookie_base) {
  335.           cookie_base=strchr(cookie_base,'\t');       // prochain tab
  336.           if (cookie_base) cookie_base++;
  337.         }
  338.       }
  339.     }
  340.     if (cookie_base) {
  341.       if ( cookie_base < limit) {
  342.         char* a = cookie_base;
  343.         while( (*a) && (*a!='\t') && (*a!='\n')) a++;
  344.         buffer[0]='\0';
  345.         strncatbuff(buffer,cookie_base,(int) (a - cookie_base));
  346.         return buffer;
  347.       } else
  348.         return "";
  349.     } else
  350.       return "";
  351.   } else
  352.     return "";
  353. }
  354. // fin cookies
  355.  
  356.  
  357.  
  358. // -- basic auth --
  359.  
  360. /* dΘclarer un rΘpertoire comme possΘdant une authentification propre */
  361. int bauth_add(t_cookie* cookie,char* adr,char* fil,char* auth) {
  362.   if (cookie) {
  363.     if (!bauth_check(cookie,adr,fil)) {       // n'existe pas dΘja
  364.       bauth_chain* chain=&cookie->auth;
  365.       char* prefix=bauth_prefix(adr,fil);
  366.       /* fin de la chaine */
  367.       while(chain->next)
  368.         chain=chain->next;
  369.       chain->next=(bauth_chain*) calloc(sizeof(bauth_chain),1);
  370.       if (chain->next) {
  371.         chain=chain->next;
  372.         chain->next=NULL;
  373.         strcpybuff(chain->auth,auth);
  374.         strcpybuff(chain->prefix,prefix);
  375.         return 1;
  376.       }
  377.     }
  378.   }
  379.   return 0;
  380. }
  381.  
  382. /* tester adr et fil, et retourner authentification si nΘcessaire */
  383. /* sinon, retourne NULL */
  384. char* bauth_check(t_cookie* cookie,char* adr,char* fil) {
  385.   if (cookie) {
  386.     bauth_chain* chain=&cookie->auth;
  387.     char* prefix=bauth_prefix(adr,fil);
  388.     while(chain) {
  389.       if (strnotempty(chain->prefix)) {
  390.         if (strncmp(prefix,chain->prefix,strlen(chain->prefix))==0) {
  391.           return chain->auth;
  392.         }
  393.       }
  394.       chain=chain->next;
  395.     }
  396.   }
  397.   return NULL;
  398. }
  399.  
  400. char* bauth_prefix(char* adr,char* fil) {
  401.   char* prefix;
  402.   char* a;
  403.   NOSTATIC_RESERVE(prefix, char, HTS_URLMAXSIZE*2);
  404.   strcpybuff(prefix,jump_identification(adr));
  405.   strcatbuff(prefix,fil);
  406.   a=strchr(prefix,'?');
  407.   if (a) *a='\0';
  408.   if (strchr(prefix,'/')) {
  409.     a=prefix+strlen(prefix)-1;
  410.     while(*a != '/') a--;
  411.     *(a+1)='\0';
  412.   }
  413.   return prefix;
  414. }
  415.